From 9e14799d6a2854ced0f3369b762448eb5cacd22d Mon Sep 17 00:00:00 2001 From: "rac61@labyrinth.cl.cam.ac.uk" Date: Tue, 8 Jul 2003 11:07:33 +0000 Subject: [PATCH] bitkeeper revision 1.289.1.2 (3f0aa5f5RZ04FODq-SZaRpQyRs03AA) Refactoring partially complete, code reformatting, cleanups, documentation Fix disk number handling so that it masks the correct number of bits. --- .../org/xenoserver/cmdline/CommandParser.java | 4 +- .../cmdline/ParsePartitionsAdd.java | 6 +- .../cmdline/ParsePartitionsList.java | 20 +- .../cmdline/ParsePhysicalGrant.java | 4 +- .../xenoserver/cmdline/ParsePhysicalList.java | 26 +- .../cmdline/ParsePhysicalRevoke.java | 2 +- .../org/xenoserver/cmdline/ParseVdCreate.java | 2 +- .../org/xenoserver/cmdline/ParseVdDelete.java | 2 +- .../org/xenoserver/cmdline/ParseVdFree.java | 12 +- .../org/xenoserver/cmdline/ParseVdShow.java | 31 +- .../control/CommandPartitionAdd.java | 4 +- .../control/CommandPhysicalList.java | 149 +++--- .../xenoserver/control/CommandVdCreate.java | 2 +- .../xenoserver/control/CommandVdDelete.java | 2 +- .../xenoserver/control/CommandVdRefresh.java | 7 +- .../src/org/xenoserver/control/Extent.java | 112 ++--- .../control/InetAddressPattern.java | 115 +++-- .../src/org/xenoserver/control/Library.java | 274 ++++++----- .../src/org/xenoserver/control/Mode.java | 32 +- .../src/org/xenoserver/control/Partition.java | 313 +++++++------ .../xenoserver/control/PartitionManager.java | 303 ++++++------- .../src/org/xenoserver/control/Settings.java | 85 ++-- .../org/xenoserver/control/StringPattern.java | 117 +++-- .../control/VirtualBlockDevice.java | 139 ++++-- .../org/xenoserver/control/VirtualDisk.java | 386 +++++++++------- .../control/VirtualDiskManager.java | 426 +++++++++--------- .../src/org/xenoserver/control/XML.java | 177 ++++---- .../src/org/xenoserver/control/XMLHelper.java | 385 ++++++++-------- 28 files changed, 1629 insertions(+), 1508 deletions(-) diff --git a/tools/control/src/org/xenoserver/cmdline/CommandParser.java b/tools/control/src/org/xenoserver/cmdline/CommandParser.java index e04b1cb7d3..35b7c236be 100644 --- a/tools/control/src/org/xenoserver/cmdline/CommandParser.java +++ b/tools/control/src/org/xenoserver/cmdline/CommandParser.java @@ -89,10 +89,10 @@ public abstract class CommandParser { } protected void loadState() { - XML.load_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_INPUT_FILE ); + XML.loadState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_INPUT_FILE ); } protected void saveState() { - XML.dump_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_OUTPUT_FILE ); + XML.saveState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_OUTPUT_FILE ); } } diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java index 63f6dce36e..67e4902b9b 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java +++ b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java @@ -19,19 +19,19 @@ public class ParsePartitionsAdd extends CommandParser { if (partition_name.equals("")) throw new ParseFailedException("Expected -p"); - long chunksize = Library.parse_size( size ) / Settings.SECTOR_SIZE; + long chunksize = Library.parseSize( size ) / Settings.SECTOR_SIZE; if ( chunksize <= 0 ) throw new CommandFailedException("Chunk size " + size + " is smaller than sector size."); // Initialise the partition manager and look up the partition loadState(); - Partition p = PartitionManager.it.get_partition(partition_name); + Partition p = PartitionManager.IT.getPartition(partition_name); if ( p == null ) throw new CommandFailedException("Partition " + partition_name + " does not exist."); // Check if this partition belongs to the VDM - if (p.getIsXeno() && !force) + if (p.isXeno() && !force) throw new CommandFailedException("Refusing to add partition as it is already allocated to the virtual disk manager. Use -f if you are sure."); String output = new CommandPartitionAdd( p, chunksize ).execute(); diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java index 7853461463..ac60c6e591 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java +++ b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java @@ -12,26 +12,26 @@ import org.xenoserver.control.PartitionManager; public class ParsePartitionsList extends CommandParser { public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException { loadState(); - Iterator i = PartitionManager.it.iterator(); + Iterator i = PartitionManager.IT.iterator(); int idx = 1; System.out.println( " maj:min " + " blocks " + "start sect " + " num sects " + "name" ); while (i.hasNext()) { Partition p = (Partition) i.next(); - if (p.getIsXeno()) { + if (p.isXeno()) { System.out.print("[ "); } else { System.out.print(" "); } - System.out.print(Library.format(idx++, 2, 0) + " "); - System.out.print(Library.format(p.getMajor(),3,0) + ":" + - Library.format(p.getMinor(),3,1) + " " + - Library.format(p.getBlocks(),10,0) + " " + - Library.format(p.getStartSect(),10,0) + " " + - Library.format(p.getNumSects(),10,0) + " " + - Library.format(p.getName(),7,1)); - if (p.getIsXeno()) { + System.out.print(Library.format(idx++, 2, false) + " "); + System.out.print(Library.format(p.getMajor(),3,false) + ":" + + Library.format(p.getMinor(),3,true) + " " + + Library.format(p.getBlocks(),10,false) + " " + + Library.format(p.getStartSect(),10,false) + " " + + Library.format(p.getNumSects(),10,false) + " " + + Library.format(p.getName(),7,true)); + if (p.isXeno()) { System.out.println("]"); } else { System.out.println(); diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java index 9979d6e4f0..af3c7a6b47 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java +++ b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java @@ -30,13 +30,13 @@ public class ParsePhysicalGrant extends CommandParser { // Initialise the partition manager and look up the partition loadState(); - Partition p = PartitionManager.it.get_partition(partition_name); + Partition p = PartitionManager.IT.getPartition(partition_name); if ( p == null ) throw new CommandFailedException("Partition " + partition_name + " does not exist."); // Check if this partition belongs to the VDM - if (p.getIsXeno() && !force) + if (p.isXeno() && !force) throw new CommandFailedException("Refusing to grant physical access as the given partition is allocated to the virtual disk manager. Use -f if you are sure."); // Convert the partition into a physical extent diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java index 84d849a28c..18a4400e80 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java +++ b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java @@ -35,23 +35,23 @@ public class ParsePhysicalList extends CommandParser { Entry entry = (Entry) i.next(); Extent e = (Extent) entry.getKey(); String mode = entry.getValue().toString(); - Partition p = PartitionManager.it.get_partition( e ); + Partition p = PartitionManager.IT.getPartition( e ); if ( p != null ) { - System.out.println(Library.format(p.getMajor(),3,0) + ":" + - Library.format(p.getMinor(),3,1) + " " + - Library.format(p.getBlocks(),10,0) + " " + - Library.format(p.getStartSect(),10,0) + " " + - Library.format(p.getNumSects(),10,0) + " " + - Library.format(p.getName(),7,1) + " " + - Library.format(mode,2,1)); + System.out.println(Library.format(p.getMajor(),3,false) + ":" + + Library.format(p.getMinor(),3,true) + " " + + Library.format(p.getBlocks(),10,false) + " " + + Library.format(p.getStartSect(),10,false) + " " + + Library.format(p.getNumSects(),10,false) + " " + + Library.format(p.getName(),7,true) + " " + + Library.format(mode,2,true)); } else { - System.out.println(Library.format(e.getMajor(),3,0) + ":" + - Library.format(e.getMinor(),3,1) + " " + + System.out.println(Library.format(e.getMajor(),3,false) + ":" + + Library.format(e.getMinor(),3,true) + " " + " " + " " + - Library.format(e.getOffset(),10,0) + " " + - Library.format(e.getSize(),10,0) + " " + + Library.format(e.getOffset(),10,false) + " " + + Library.format(e.getSize(),10,false) + " " + " " + " " + - Library.format(mode,2,1)); + Library.format(mode,2,true)); } } } diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java index 9db83a5b85..5c0e80201f 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java +++ b/tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java @@ -21,7 +21,7 @@ public class ParsePhysicalRevoke extends CommandParser { // Initialise the partition manager and look up the partition loadState(); - Partition p = PartitionManager.it.get_partition(partition_name); + Partition p = PartitionManager.IT.getPartition(partition_name); if ( p == null ) throw new CommandFailedException("Partition " + partition_name + " does not exist."); diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java b/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java index 9075039a29..4f4210f22f 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java +++ b/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java @@ -25,7 +25,7 @@ public class ParseVdCreate extends CommandParser { else expiry = new Date(Date.parse(expiry_s)); - long size = Library.parse_size(size_s); + long size = Library.parseSize(size_s); loadState(); String output = new CommandVdCreate(name,size/Settings.SECTOR_SIZE,expiry).execute(); diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java b/tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java index 20713e5366..bcd400876e 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java +++ b/tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java @@ -15,7 +15,7 @@ public class ParseVdDelete extends CommandParser { throw new ParseFailedException("Expected -k"); loadState(); - if ( VirtualDiskManager.it.get_virtual_disk_key(vd_key) == null ) + if ( VirtualDiskManager.IT.getVirtualDisk(vd_key) == null ) throw new CommandFailedException("Virtual disk " + vd_key + " does not exist"); String output = new CommandVdDelete(vd_key).execute(); diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java b/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java index 7bd3e8a804..ea62f8998f 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java +++ b/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java @@ -16,17 +16,17 @@ public class ParseVdFree extends CommandParser { boolean verbose = getFlagParameter(args, 'v'); loadState(); - VirtualDisk free = VirtualDiskManager.it.getFreeVirtualDisk(); + VirtualDisk free = VirtualDiskManager.IT.getFreeDisk(); System.out.println( "Free disk has " + free.getExtentCount() + " extents totalling " - + Library.format_size(free.getSize()*Settings.SECTOR_SIZE,8,1) ); + + Library.formatSize(free.getSize()*Settings.SECTOR_SIZE,8,true) ); if ( verbose ) { - Iterator i = free.iterator(); + Iterator i = free.extents(); System.out.println(" disk offset size"); while (i.hasNext()) { Extent e = (Extent) i.next(); - System.out.println( Library.format(e.getDisk(), 6, 0) + " " - + Library.format(e.getOffset(), 12, 0) + " " - + Library.format(e.getSize(), 12, 0) ); + System.out.println( Library.format(e.getDisk(), 6, false) + " " + + Library.format(e.getOffset(), 12, false) + " " + + Library.format(e.getSize(), 12, false) ); } } } diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java b/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java index 287a24621a..af65573902 100644 --- a/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java +++ b/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java @@ -13,41 +13,42 @@ import org.xenoserver.control.VirtualDiskManager; public class ParseVdShow extends CommandParser { public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException { - int vd_num = getIntParameter(args,'n',-1); + String key = getStringParameter(args,'k',""); loadState(); - if ( vd_num < 0 ) { - System.out.println("num key expiry name size"); - for (int i=0;i> 8; - } - - public int - getMinor() - { - return disk & 0xFF; - } - - public int hashCode() { - final int PRIME = 1000003; - int result = 0; - result = PRIME * result + disk; - result = PRIME * result + (int) (offset >>> 32); - result = PRIME * result + (int) (offset & 0xFFFFFFFF); - result = PRIME * result + (int) (size >>> 32); - result = PRIME * result + (int) (size & 0xFFFFFFFF); - - return result; - } +/** + * Represents an extent on physical disk. + */ +public class Extent { + /** Disk number; 16-bit major:minor pair with no partition number. */ + private int disk; + /** Offset into disk in sectors. */ + private long offset; + /** Size of extent in sectors. */ + private long size; - public boolean equals(Object oth) { - if (this == oth) { - return true; + /** + * Constructor for Extent. + * @param disk Disk number. + * @param offset Offset into disk. + * @param size Size of extent. + */ + Extent(int disk, long offset, long size) { + this.disk = disk; + this.offset = offset; + this.size = size; } - if (oth == null) { - return false; + /** + * @return Disk number. + */ + public int getDisk() { + return disk; } - if (oth.getClass() != getClass()) { - return false; + /** + * @return Offset into disk. + */ + public long getOffset() { + return offset; } - Extent other = (Extent) oth; - - if (this.disk != other.disk) { - return false; + /** + * @return Size of extent. + */ + public long getSize() { + return size; } - if (this.offset != other.offset) { - return false; + /** + * @return Major number of disk. + */ + public int getMajor() { + return disk >> 8; } - if (this.size != other.size) { - return false; + /** + * @return Minor number of disk, not including partition. + */ + public int getMinor() { + return disk & 0xFF; } - - return true; - } - } diff --git a/tools/control/src/org/xenoserver/control/InetAddressPattern.java b/tools/control/src/org/xenoserver/control/InetAddressPattern.java index 79c2385ef8..90108dd250 100644 --- a/tools/control/src/org/xenoserver/control/InetAddressPattern.java +++ b/tools/control/src/org/xenoserver/control/InetAddressPattern.java @@ -3,58 +3,77 @@ package org.xenoserver.control; import java.net.InetAddress; import java.net.UnknownHostException; -public class InetAddressPattern -{ - InetAddress base; - boolean addDom; +/** + * This utility class expands configuration file patterns. + */ +public class InetAddressPattern { + /** The base InetAddress for this pattern. */ + private InetAddress base; + /** If true, add the domain number to the base address. */ + private boolean addDom; - static InetAddressPattern parse (String t) - { - InetAddressPattern result = new InetAddressPattern (); - char[] ca = t.toCharArray (); - int len = ca.length; + /** + * Parse a pattern string into an InetAddressPattern. + * @param t The pattern string. + * @return The parsed pattern object. + */ + static InetAddressPattern parse(String t) { + InetAddressPattern result = new InetAddressPattern(); + char[] ca = t.toCharArray(); + int len = ca.length; - try { - if (len == 0) { - result.base = null; - result.addDom = false; - } else if (ca[len - 1] == '+') { - result.base = InetAddress.getByName(t.substring(0, len - 1)); - result.addDom = true; - } else { - result.base = InetAddress.getByName(t); - result.addDom = false; - } - } catch (UnknownHostException uhe) { - result.base = null; - result.addDom = false; - } + try { + if (len == 0) { + result.base = null; + result.addDom = false; + } else if (ca[len - 1] == '+') { + result.base = InetAddress.getByName(t.substring(0, len - 1)); + result.addDom = true; + } else { + result.base = InetAddress.getByName(t); + result.addDom = false; + } + } catch (UnknownHostException uhe) { + result.base = null; + result.addDom = false; + } - return result; - } + return result; + } - public String resolve (int domain_id) { - byte b[] = base.getAddress (); - if (addDom) { - if (((int)b[3]) + domain_id > 255) { - if (((int)b[2]) + domain_id > 255) { - if (((int)b[1]) + domain_id > 255) { - b[0] ++; - } - b[1] ++; - } - b[2] ++; - } - b[3] += domain_id; + /** + * Resolve the pattern for the given domain. + * @param domain_id The domain ID. + * @return The resolved string. + */ + String resolve(int domain_id) { + byte[] b = base.getAddress(); + if (addDom) { + if (((int) b[3]) + domain_id > 255) { + if (((int) b[2]) + domain_id > 255) { + if (((int) b[1]) + domain_id > 255) { + b[0]++; + } + b[1]++; + } + b[2]++; + } + b[3] += domain_id; + } + return "" + + (b[0] + (b[0] < 0 ? 256 : 0)) + + "." + + (b[1] + (b[1] < 0 ? 256 : 0)) + + "." + + (b[2] + (b[2] < 0 ? 256 : 0)) + + "." + + (b[3] + (b[3] < 0 ? 256 : 0)); } - return "" + - (b[0] + (b[0] < 0 ? 256 : 0)) + "." + - (b[1] + (b[1] < 0 ? 256 : 0)) + "." + - (b[2] + (b[2] < 0 ? 256 : 0)) + "." + - (b[3] + (b[3] < 0 ? 256 : 0)); - } - public String toString () { - return "[" + base + (addDom ? "+dom_id" : "") + "]"; - } + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return "[" + base + (addDom ? "+dom_id" : "") + "]"; + } } diff --git a/tools/control/src/org/xenoserver/control/Library.java b/tools/control/src/org/xenoserver/control/Library.java index d79e01aef5..eb90218940 100644 --- a/tools/control/src/org/xenoserver/control/Library.java +++ b/tools/control/src/org/xenoserver/control/Library.java @@ -5,162 +5,144 @@ package org.xenoserver.control; -public class -Library -{ - /* - * convert a number to a fixed width string - */ - public static String - format (long input, int width, int prefix) - { - String sss = Long.toString(input); - String space = " "; - - if (width < sss.length()) - { - width = sss.length(); - } +/** + * Library functions. + */ +public class Library { + /** + * Convert a number to a fixed width string. + * @param input The number to convert. + * @param width The width desired. + * @param leftAlign True to left-align the number. + * @return The formatted string. + */ + public static String format(long input, int width, boolean leftAlign) { + String sss = Long.toString(input); + String space = " "; - if (prefix == 0) - { - return space.substring(0, width - sss.length()) + sss; - } - else - { - return sss + space.substring(0, width - sss.length()); - } - } - - /* - * convert a string to a fixed width string - */ - public static String - format (String input, int width, int prefix) - { - String space = " "; - - if (width < input.length()) - { - width = input.length(); - } + if (width < sss.length()) { + width = sss.length(); + } - if (prefix == 0) - { - return space.substring(0, width - input.length()) + input; - } - else - { - return input + space.substring(0, width - input.length()); - } - } - - /* - * convert a number (string format) into - * the corresponding integer value. - */ - public static long - parse_size(String size) - { - String substring = size; - int suffix = 1; - long value = 0; - - if (size == null) - { - return 0; + if (leftAlign) { + return sss + space.substring(0, width - sss.length()); + } else { + return space.substring(0, width - sss.length()) + sss; + } } - if ((substring = check(size, 'm')) != null) - { - suffix = 1024 * 1024; - } - else if ((substring = check(size, 'M')) != null) - { - suffix = 1024 * 1024; - } - else if ((substring = check(size, 'k')) != null) - { - suffix = 1024; - } - else if ((substring = check(size, 'K')) != null) - { - suffix = 1024; - } - else if ((substring = check(size, 'g')) != null) - { - suffix = 1024 * 1024 * 1024; - } - else if ((substring = check(size, 'G')) != null) - { - suffix = 1024 * 1024 * 1024; - } - else - { - substring = size; - } + /** + * Convert a string to a fixed-width string. + * @param input Input string. + * @param width Width desired. + * @param leftAlign True to left-align the string. + * @return The formatted string. + */ + public static String format(String input, int width, boolean leftAlign) { + String space = " "; - try - { - value = Long.decode(substring).longValue() * suffix; - } - catch (NumberFormatException e) - { - value = 0; + if (width < input.length()) { + width = input.length(); + } + + if (leftAlign) { + return input + space.substring(0, width - input.length()); + } else { + return space.substring(0, width - input.length()) + input; + } } - return value; - } + /** + * Parse a size which may have a k/m/g suffix into a number. + * @param size The size string to parse. + * @return The equivalent number. + */ + public static long parseSize(String size) { + String substring = size; + int suffix = 1; + long value = 0; - public static String - check(String size, char suffix) - { - int index = size.indexOf(suffix); + if (size == null) { + return 0; + } - if (index != -1) - { - return size.substring(0, index); - } - else - { - return null; + if ((substring = check(size, 'm')) != null) { + suffix = 1024 * 1024; + } else if ((substring = check(size, 'M')) != null) { + suffix = 1024 * 1024; + } else if ((substring = check(size, 'k')) != null) { + suffix = 1024; + } else if ((substring = check(size, 'K')) != null) { + suffix = 1024; + } else if ((substring = check(size, 'g')) != null) { + suffix = 1024 * 1024 * 1024; + } else if ((substring = check(size, 'G')) != null) { + suffix = 1024 * 1024 * 1024; + } else { + substring = size; + } + + try { + value = Long.decode(substring).longValue() * suffix; + } catch (NumberFormatException e) { + value = 0; + } + + return value; } - } - - /** - * Formats a number of bytes in whichever way makes most sense based - * on magnitude and width. - * - * @param size Number of bytes. - * @param width Width of field - at least 5, plz. - * @param prefix Set to 1 for left justify - * @return The formatted string. - */ - public static String format_size(long size,int width,int prefix) { - char[] suffixes = { ' ', 'k', 'M', 'G' }; - int suffix = 0; - long before = size; - float after = 0; - - while ( before > 10000 ) { - after = ((float)(before % 1024)) / 1024; - before /= 1024; - suffix++; + + /** + * Check if the given size has the specified suffix. + * @param size Size string. + * @param suffix Test suffix. + * @return Number part of string, or null if suffix does not match. + */ + private static String check(String size, char suffix) { + int index = size.indexOf(suffix); + + if (index != -1) { + return size.substring(0, index); + } else { + return null; + } } - - StringBuffer num = new StringBuffer(width); - num.append( Long.toString( before ) ); - if ( after != 0 ) { - int space = width - num.length() - 2; - if ( space > 0 ) { - num.append( '.' ); - if ( space > 3 ) - space = 3; - num.append( Integer.toString( (int) (after * Math.pow(10,space)))); - } + + /** + * Formats a number of bytes in whichever way makes most sense based + * on magnitude and width. + * + * @param size Number of bytes. + * @param width Width of field - at least 5, plz. + * @param leftAlign True for left-align. + * @return The formatted string. + */ + public static String formatSize(long size, int width, boolean leftAlign) { + char[] suffixes = { ' ', 'k', 'M', 'G' }; + int suffix = 0; + long before = size; + float after = 0; + + while (before > 10000) { + after = ((float) (before % 1024)) / 1024; + before /= 1024; + suffix++; + } + + StringBuffer num = new StringBuffer(width); + num.append(Long.toString(before)); + if (after != 0) { + int space = width - num.length() - 2; + if (space > 0) { + num.append('.'); + if (space > 3) { + space = 3; + } + num.append( + Integer.toString((int) (after * Math.pow(10, space)))); + } + } + num.append(suffixes[suffix]); + + return format(num.toString(), width, leftAlign); } - num.append( suffixes[suffix] ); - - return format(num.toString(),width,prefix); - } } diff --git a/tools/control/src/org/xenoserver/control/Mode.java b/tools/control/src/org/xenoserver/control/Mode.java index 5f2ea4d485..e9621604a1 100644 --- a/tools/control/src/org/xenoserver/control/Mode.java +++ b/tools/control/src/org/xenoserver/control/Mode.java @@ -7,16 +7,30 @@ package org.xenoserver.control; -public class -Mode -{ - private final String name; +/** + * Enumeration to represent an access mode. + */ +public class Mode { + /** name of this mode */ + private final String name; - private Mode(String name) { this.name = name; } + /** + * Construct a mode + * @param name Name to use. + */ + private Mode(String name) { + this.name = name; + } - public String toString() { return name; } + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return name; + } - public static final Mode READ_ONLY = new Mode("ro"); - public static final Mode READ_WRITE = new Mode("rw"); + /** Single read-only mode instance. */ + public static final Mode READ_ONLY = new Mode("ro"); + /** Single read-write mode instance. */ + public static final Mode READ_WRITE = new Mode("rw"); } - diff --git a/tools/control/src/org/xenoserver/control/Partition.java b/tools/control/src/org/xenoserver/control/Partition.java index 85ea7e3728..510e266813 100644 --- a/tools/control/src/org/xenoserver/control/Partition.java +++ b/tools/control/src/org/xenoserver/control/Partition.java @@ -7,184 +7,179 @@ package org.xenoserver.control; import java.io.PrintWriter; -public class -Partition -{ - int major; - int minor; - long blocks; - long start_sect; - long nr_sects; - String name; - boolean xeno; - - Partition - duplicate () - { - Partition p = new Partition(); - - p.major = major; - p.minor = minor; - p.blocks = blocks; - p.start_sect = start_sect; - p.nr_sects = nr_sects; - p.name = name; - p.xeno = xeno; - - return p; - } - - void - dump_xml(PrintWriter out) - { - out.println (" \n" + - " " + major + "\n" + - " " + minor + "\n" + - " " + blocks + "\n" + - " " + start_sect + "\n" + - " " + nr_sects + "\n" + - " " + name + "\n" + - " "); - } - - public int - getMajor() - { - return major; - } - - public int - getMinor() - { - return minor; - } - - public long - getBlocks() - { - return blocks; - } - - public long - getStartSect() - { - return start_sect; - } - - public long - getNumSects() - { - return nr_sects; - } - - public String - getName() - { - return name; - } - - public boolean - getIsXeno() - { - return xeno; - } - - public int hashCode() { - final int PRIME = 1000003; - int result = 0; - result = PRIME * result + major; - result = PRIME * result + minor; - result = PRIME * result + (int) (blocks >>> 32); - result = PRIME * result + (int) (blocks & 0xFFFFFFFF); - result = PRIME * result + (int) (start_sect >>> 32); - result = PRIME * result + (int) (start_sect & 0xFFFFFFFF); - result = PRIME * result + (int) (nr_sects >>> 32); - result = PRIME * result + (int) (nr_sects & 0xFFFFFFFF); - if (name != null) { - result = PRIME * result + name.hashCode(); +/** + * Represents a single real partition. + */ +public class Partition { + /** Major device number as seen by Linux. */ + private int major; + /** Minor device number as seen by Linux. */ + private int minor; + /** Number of blocks in the partition. */ + private long blocks; + /** Start sector of the partition. */ + private long start_sect; + /** Number of sectors in the partition. */ + private long nr_sects; + /** Name of the partition. */ + private String name; + /** True if this partition is a XenoPartition. */ + private boolean xeno; + + /** + * Mark this partition as a XenoPartition. + */ + void makeXeno() { + xeno = true; } - return result; - } + /** + * Constructor for Partition. + * @param major Major number + * @param minor Minor number + * @param blocks Size in blocks + * @param start_sect Start sector + * @param nr_sects Number of sectors + * @param name Name of partition + * @param xeno True if XenoPartition + */ + Partition( + int major, + int minor, + long blocks, + long start_sect, + long nr_sects, + String name, + boolean xeno) { + this.major = major; + this.minor = minor; + this.blocks = blocks; + this.start_sect = start_sect; + this.nr_sects = nr_sects; + this.name = name; + this.xeno = xeno; + } - public boolean equals(Object oth) { - if (this == oth) { - return true; + /** + * Dump this partition as XML. + * @param out The writer to dump to. + */ + void dumpAsXML(PrintWriter out) { + out.println( + " \n" + + " " + + major + + "\n" + + " " + + minor + + "\n" + + " " + + blocks + + "\n" + + " " + + start_sect + + "\n" + + " " + + nr_sects + + "\n" + + " " + + name + + "\n" + + " "); } - if (oth == null) { - return false; + /** + * @return Major device number. + */ + public int getMajor() { + return major; } - if (oth.getClass() != getClass()) { - return false; + /** + * @return Minor device number. + */ + public int getMinor() { + return minor; } - Partition other = (Partition) oth; + /** + * @return Number of blocks. + */ + public long getBlocks() { + return blocks; + } - if (this.major != other.major) { - return false; + /** + * @return Starting sector. + */ + public long getStartSect() { + return start_sect; } - if (this.minor != other.minor) { - return false; + /** + * @return Number of sectors. + */ + public long getNumSects() { + return nr_sects; } - if (this.blocks != other.blocks) { - return false; + /** + * @return Name of partition. + */ + public String getName() { + return name; } - if (this.start_sect != other.start_sect) { - return false; + /** + * @return True if this is a XenoPartition. + */ + public boolean isXeno() { + return xeno; } - if (this.nr_sects != other.nr_sects) { - return false; + /** + * Is this partition identical to the other? + * @param other Other partition to compare to. + * @return True if they are identical. + */ + public boolean identical(Partition other) { + return this.major == other.major + && this.minor == other.minor + && this.blocks == other.blocks + && this.start_sect == other.start_sect + && this.nr_sects == other.nr_sects + && this.name.equals(other.name); } - if (this.name == null) { - if (other.name != null) { - return false; - } - } else { - if (!this.name.equals(other.name)) { - return false; - } + + /** + * @return An Extent covering this partiton. + */ + public Extent toExtent() { + return new Extent(getDisk(),start_sect,nr_sects); } - return true; - } - - /** - * @return An Extent covering this partiton. - */ - public Extent toExtent() - { - Extent e = new Extent(); - // Build 16-bit disk number.. high 8 bits are the major - e.disk = major << 8; - // Low 8 bits are the minor, but bottom 5 need to be cleared - // as they are the partition number, not the disk number - e.disk |= ( minor & 0xE0 ); - e.offset = start_sect; - e.size = nr_sects; - return e; - } - - /** - * @param e Extent to compare this partition to. - * @return True if this partition covers the same disk area as the given extent. - */ - public boolean matchesExtent( Extent e ) - { - if ( e.getMajor() != major ) - return false; - if ( e.getMinor() != minor ) - return false; - if ( e.offset != start_sect ) - return false; - if ( e.size != nr_sects ) - return false; - - return true; - } + /** + * @param e Extent to compare this partition to. + * @return True if this partition covers the same disk area as the given extent. + */ + public boolean matchesExtent(Extent e) { + return e.getDisk() == getDisk() + && e.getOffset() == start_sect + && e.getSize() == nr_sects; + } + + /** + * @return Disk number for this partition. + */ + public int getDisk() { + if ( name.startsWith("hd") ) { + // High 8 bits are major, low 8 bits are minor, with bottom 6 clear + return (major << 8) | (minor & 0xC0); + } else if ( name.startsWith("sd") ) { + // High 8 bits are major, low 8 bits are minor, with bottom 4 clear + return (major << 8) | (minor & 0xF0); + } else { + throw new IllegalArgumentException("Don't know how to convert " + name + "into a disk number"); + } + } } diff --git a/tools/control/src/org/xenoserver/control/PartitionManager.java b/tools/control/src/org/xenoserver/control/PartitionManager.java index 2c93636762..b638e14922 100644 --- a/tools/control/src/org/xenoserver/control/PartitionManager.java +++ b/tools/control/src/org/xenoserver/control/PartitionManager.java @@ -17,170 +17,155 @@ import java.util.Vector; * PartitionManager manages the partitions on the machine. It is a Singleton * which automatically initialises itself on first class reference. */ -public class -PartitionManager -{ - static final String proc_template = - "major minor #blocks start_sect nr_sects name"; - - public static final PartitionManager it = new PartitionManager(Settings.PARTITIONS_FILE); - - Vector partition_map; - - /* - * Initialize partition manager with source file. - * Normally we read from /proc/partitions, but we can - * specify an alternative file for debugging - */ - private PartitionManager (String filename) - { - String str; - BufferedReader in; - - partition_map = new Vector(100,10); - - try - { - in = new BufferedReader(new FileReader(filename)); - - str = in.readLine(); /* skip headings */ - if (str.length() < proc_template.length() || - !str.substring(0, proc_template.length()).equals(proc_template)) - { - System.err.println ("Error: Incorrect /proc/partitions."); - System.err.println (" Is this Xeno?"); - System.exit (1); - } - - str = in.readLine(); /* skip blank line */ - - str = in.readLine(); - while (str != null) - { - Partition partition = new Partition(); - - partition.major = Integer.parseInt(str.substring(0,5).trim()); - partition.minor = Integer.parseInt(str.substring(5,10).trim()); - partition.blocks = Integer.parseInt(str.substring(10,21).trim()); - partition.start_sect = Integer.parseInt(str.substring(21,32).trim()); - partition.nr_sects = Integer.parseInt(str.substring(32,43).trim()); - partition.name = str.substring(43).trim(); - partition.xeno = false; - - partition_map.add(partition); - str = in.readLine(); - } +public class PartitionManager { + /** The proc header string, used to check that this is a suitable proc file. */ + private static final String PROC_TEMPLATE = + "major minor #blocks start_sect nr_sects name"; + + /** The single PartitionManager reference. */ + public static final PartitionManager IT = + new PartitionManager(Settings.PARTITIONS_FILE); + + /** The list of partitions. */ + private Vector partition_map; + + /** + * Initialize partition manager with source file. + * Normally we read from /proc/partitions, but we can + * specify an alternative file for debugging. + * @param filename The file to read partition data from. + */ + private PartitionManager(String filename) { + String str; + BufferedReader in; + + partition_map = new Vector(100, 10); + + try { + in = new BufferedReader(new FileReader(filename)); + + str = in.readLine(); /* skip headings */ + if (str.length() < PROC_TEMPLATE.length() + || !str.substring(0, PROC_TEMPLATE.length()).equals( + PROC_TEMPLATE)) { + System.err.println("Error: Incorrect /proc/partitions."); + System.err.println(" Is this Xeno?"); + System.exit(1); + } + + str = in.readLine(); /* skip blank line */ + + str = in.readLine(); + while (str != null) { + Partition partition = + new Partition( + Integer.parseInt(str.substring(0, 5).trim()), + Integer.parseInt(str.substring(5, 10).trim()), + Integer.parseInt(str.substring(10, 21).trim()), + Integer.parseInt(str.substring(21, 32).trim()), + Integer.parseInt(str.substring(32, 43).trim()), + str.substring(43).trim(), + false); + + partition_map.add(partition); + str = in.readLine(); + } + } catch (IOException io) { + System.err.println( + "PartitionManager: error reading partition file [" + + filename + + "]"); + System.err.println(io); + } } - catch (IOException io) - { - System.err.println ("PartitionManager: error reading partition file [" - + filename + "]"); - System.err.println (io); + + /** + * Find a partition with the specified name. + * @param name The name to search for. + * @return The partition found, or null if no such partition. + */ + public Partition getPartition(String name) { + Partition partition = null; + for (Enumeration e = partition_map.elements(); e.hasMoreElements();) { + partition = (Partition) e.nextElement(); + if (partition.getName().equals(name)) { + return partition; + } + } + return null; + } + + /** + * Finds the partition that matches the given extent, if any. + * @param extent The extent to compare to. + * @return The first matching partition, or null if none. + */ + public Partition getPartition(Extent extent) { + Partition partition = null; + for (Enumeration e = partition_map.elements(); e.hasMoreElements();) { + partition = (Partition) e.nextElement(); + if (partition.matchesExtent(extent)) { + return partition; + } + } + return null; } - } - - public Partition - get_partition (String name) - { - Partition partition = null; - for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) - { - partition = (Partition) e.nextElement(); - if (partition.name.equals(name)) - { - return partition; - } + + /** + * Find the ith partition in the partition list. + * @param i Index number. + * @return The partition, or null if out of range. + */ + public Partition getPartition(int i) { + if ( i >= partition_map.size() ) { + return null; + } + return (Partition) partition_map.elementAt( i ); } - return null; - } - - /** - * Finds the partition that matches the given extent, if any. - * @param extent The extent to compare to. - * @return The first matching partition, or null if none. - */ - public Partition - get_partition (Extent extent) - { - Partition partition = null; - for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) - { - partition = (Partition) e.nextElement(); - if (partition.matchesExtent(extent)) - { - return partition; - } + + /** + * Adds the given partition as a XenoPartition. + * @param p The partition to add. + */ + void addXenoPartition(Partition p) { + for (Enumeration e = partition_map.elements(); e.hasMoreElements();) { + Partition partition = (Partition) e.nextElement(); + if (partition.identical(p)) { + partition.makeXeno(); + } + } } - return null; - } - - Partition - get_partition (int index) - { - return (Partition) partition_map.get(index); - } - - void - add_xeno_partition (Partition p) - { - for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) - { - Partition partition = (Partition) e.nextElement(); - if (partition.equals(p)) - { - partition.xeno = true; - } + + /** + * Dump the XenoPartition list as XML. + * @param out Writer to dump to. + */ + void dumpAsXML(PrintWriter out) { + out.println(""); + for (Enumeration e = partition_map.elements(); e.hasMoreElements();) { + Partition partition = (Partition) e.nextElement(); + if (partition.isXeno()) { + partition.dumpAsXML(out); + } + } + + out.println(""); + + return; } - } - - /* - * dump the xeno partition list as xml - */ - void - dump_xml (PrintWriter out) - { - out.println(""); - for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) - { - Partition partition = (Partition) e.nextElement(); - if (partition.xeno == true) - { - partition.dump_xml(out); - } + + /** + * @return The number of partitions. + */ + public int getPartitionCount() { + return partition_map.size(); } - out.println(""); - - return; - } - - /** - * get the number of partitions - */ - - int - getPartitionCount () - { - return partition_map.size(); - } - - /** - * get the details about a particular partition - * - */ - Partition - getPartition (int index) - { - Partition partition = (Partition) partition_map.get(index); - return partition; - } - - /** - * Get an iterator over all the partitions. - * @return An iterator over Partition objects. - */ - public Iterator iterator() - { - return partition_map.iterator(); - } + /** + * Get an iterator over all the partitions. + * @return An iterator over Partition objects. + */ + public Iterator iterator() { + return partition_map.iterator(); + } } diff --git a/tools/control/src/org/xenoserver/control/Settings.java b/tools/control/src/org/xenoserver/control/Settings.java index a51a7212a6..4d9ca628cc 100644 --- a/tools/control/src/org/xenoserver/control/Settings.java +++ b/tools/control/src/org/xenoserver/control/Settings.java @@ -7,38 +7,63 @@ import java.util.StringTokenizer; * The Settings class is a repository for global settings such as the IP of * the machine and the location of the defaults file. */ -public final class Settings -{ - public static final String DEFAULTS_FILE = System.getProperty ("DEFAULTS_FILE", "domctl.xml"); - public static final String DEFAULTS_PATH = System.getProperty ("DEFAULTS_PATH", ".:/etc:/var/lib/xen"); - public static final String LOCAL_IP = System.getProperty ("LOCAL_IP"); - public static final String LOCAL_MASK = System.getProperty ("LOCAL_MASK"); - public static final String LOCAL_GW = System.getProperty ("LOCAL_ROUTE"); - public static final boolean TEST = (System.getProperty ("TEST") != null); - public static final String XI_HELPER = System.getProperty ("XI_HELPER", "xi_helper"); - public static final String PARTITIONS_FILE = System.getProperty("PARTITIONS_FILE", "/proc/partitions"); - public static final String STATE_INPUT_FILE = System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml"); - public static final String STATE_OUTPUT_FILE = System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml"); - public static final int SECTOR_SIZE = Integer.parseInt( System.getProperty("SECTOR_SIZE", "512") ); +public final class Settings { + /** Filename for the defaults file. */ + public static final String DEFAULTS_FILE = + System.getProperty("DEFAULTS_FILE", "domctl.xml"); + /** Path to search for the defaults file. */ + public static final String DEFAULTS_PATH = + System.getProperty("DEFAULTS_PATH", ".:/etc:/var/lib/xen"); + /** IP address of domain 0. */ + public static final String LOCAL_IP = System.getProperty("LOCAL_IP"); + /** Network mask of domain 0. */ + public static final String LOCAL_MASK = System.getProperty("LOCAL_MASK"); + /** Gateway of domain 0. */ + public static final String LOCAL_GW = System.getProperty("LOCAL_ROUTE"); + /** If set, do not call any xi_ commands, just print their command lines. */ + public static final boolean TEST = (System.getProperty("TEST") != null); + /** Name of xi_helper utility. */ + public static final String XI_HELPER = + System.getProperty("XI_HELPER", "xi_helper"); + /** File to parse to get partition info. */ + public static final String PARTITIONS_FILE = + System.getProperty("PARTITIONS_FILE", "/proc/partitions"); + /** File to load virtual disk state from. */ + public static final String STATE_INPUT_FILE = + System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml"); + /** File to save virtual disk state to. */ + public static final String STATE_OUTPUT_FILE = + System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml"); + /** Size of a sector in bytes. */ + public static final int SECTOR_SIZE = + Integer.parseInt(System.getProperty("SECTOR_SIZE", "512")); - public static File getDefaultsFile() { - StringTokenizer tok = new StringTokenizer (DEFAULTS_PATH, ":"); - File result = null; - File probe; + /** + * Search for the defaults file in the path configured in DEFAULTS_PATH. + * @return Reference to the defaults file. + */ + public static File getDefaultsFile() { + StringTokenizer tok = new StringTokenizer(DEFAULTS_PATH, ":"); + File result = null; + File probe; - while (tok.hasMoreTokens ()) { - String probe_dir = tok.nextToken (); - probe = new File (probe_dir, DEFAULTS_FILE); - if (probe.exists ()) { - result = probe; - break; - } - } + while (tok.hasMoreTokens()) { + String probe_dir = tok.nextToken(); + probe = new File(probe_dir, DEFAULTS_FILE); + if (probe.exists()) { + result = probe; + break; + } + } - if (result == null) { - System.err.println ("Could not find " + DEFAULTS_FILE + " in path " + DEFAULTS_PATH); - } + if (result == null) { + System.err.println( + "Could not find " + + DEFAULTS_FILE + + " in path " + + DEFAULTS_PATH); + } - return result; - } + return result; + } } diff --git a/tools/control/src/org/xenoserver/control/StringPattern.java b/tools/control/src/org/xenoserver/control/StringPattern.java index 5df2470a91..111a5271fa 100644 --- a/tools/control/src/org/xenoserver/control/StringPattern.java +++ b/tools/control/src/org/xenoserver/control/StringPattern.java @@ -1,59 +1,78 @@ package org.xenoserver.control; -public class StringPattern -{ - String base; - int bn; - boolean addDom; - boolean appendDom; +/** + * This utility class expands configuration file patterns. + */ +public class StringPattern { + /** The base string for this pattern. */ + private String base; + /** The base number for this pattern. */ + private int bn; + /** If true, add the domain number to the base number and append. */ + private boolean addDom; + /** If true, append the domain number to the base string. */ + private boolean appendDom; - static StringPattern parse (String t) - { - StringPattern result = new StringPattern (); - char[] ca = t.toCharArray (); - int idx = 0; - int len = ca.length; + /** + * Parse a string into a pattern. + * @param t The pattern string to parse. + * @return A usable pattern object. + */ + static StringPattern parse(String t) { + StringPattern result = new StringPattern(); + char[] ca = t.toCharArray(); + int idx = 0; + int len = ca.length; - if (len == 0) { - result.base = ""; - result.bn = 0; - result.addDom = false; - } else if (ca[len - 1] == '+') { - idx = len - 2; - if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) { - while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) { - idx --; - } - result.base = t.substring(0, idx + 1); - result.bn = Integer.parseInt (t.substring (idx + 1, len - 1)); - result.addDom = true; - } else { - result.base = t.substring(0, len - 1); - result.appendDom = true; - } - } else { - result.base = t; - } + if (len == 0) { + result.base = ""; + result.bn = 0; + result.addDom = false; + } else if (ca[len - 1] == '+') { + idx = len - 2; + if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) { + while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) { + idx--; + } + result.base = t.substring(0, idx + 1); + result.bn = Integer.parseInt(t.substring(idx + 1, len - 1)); + result.addDom = true; + } else { + result.base = t.substring(0, len - 1); + result.appendDom = true; + } + } else { + result.base = t; + } - return result; - } + return result; + } - public String resolve (int domain_id) { - if (addDom) { - return base + (bn + domain_id); - } else if (appendDom) { - return base + domain_id; - } else { - return base; + /** + * Resolve the pattern for the given domain number. + * @param domain The domain number to use. + * @return The expanded pattern for the given domain. + */ + String resolve(int domain) { + if (addDom) { + return base + (bn + domain); + } else if (appendDom) { + return base + domain; + } else { + return base; + } } - } - public String toString () { - return ("[" + - base + - (addDom ? "+" + bn : "") + - ((addDom || appendDom) ? "+ID" : "") + - "]"); - } + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return ( + "[" + + base + + (addDom ? "+" + bn : "") + + ((addDom || appendDom) ? "+ID" : "") + + "]"); + } } diff --git a/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java b/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java index c2e800789f..e66753480e 100644 --- a/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java +++ b/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java @@ -7,55 +7,98 @@ package org.xenoserver.control; import java.io.PrintWriter; +/** + * A virtual block device; a mapping from a domain-specific number to a virtual + * disk with associated access mode. + */ public class VirtualBlockDevice { - String key; - int domain; - int vbdnum; - Mode mode; /* rw or ro */ - - String dump(boolean title) { - StringBuffer sb = new StringBuffer(); - - if (title) { - sb.append(" key dom vbd mode\n"); - } else { - sb.append( - " " - + key - + " " - + Library.format(domain, 3, 0) - + " " - + Library.format(vbdnum, 3, 0) - + " " - + mode.toString() - + "\n"); + /** The virtual disk which this block device maps onto. */ + private VirtualDisk vd; + /** The domain in which this block device exists. */ + private int domain; + /** The block device number in that domain. */ + private int vbdNum; + /** The access mode within that domain. */ + private Mode mode; + + /** + * Constructor for VirtualBlockDevice. + * @param vd The virtual disk to map to. + * @param domain The domain to create the device in. + * @param vbdNum The number for the device. + * @param mode The access mode. + */ + VirtualBlockDevice( + VirtualDisk vd, + int domain, + int vbdNum, + Mode mode) { + this.vd = vd; + this.domain = domain; + this.vbdNum = vbdNum; + this.mode = mode; + } + + // TODO: get rid of this method + String dump(boolean title) { + StringBuffer sb = new StringBuffer(); + + if (title) { + sb.append(" key dom vbd mode\n"); + } else { + sb.append( + " " + + vd.getKey() + + " " + + Library.format(domain, 3, false) + + " " + + Library.format(vbdNum, 3, false) + + " " + + mode.toString() + + "\n"); + } + + return sb.toString(); + } + + /** + * Dump the virtual block device as XML. + * @param out The writer to dump to. + */ + void dumpAsXML(PrintWriter out) { + out.println(" "); + out.println(" " + vd.getKey() + ""); + out.println(" " + domain + ""); + out.println(" " + vbdNum + ""); + out.println(" " + mode + ""); + out.println(" "); } - return sb.toString(); - } - - void dump_xml(PrintWriter out) { - out.println(" "); - out.println(" " + key + ""); - out.println(" " + domain + ""); - out.println(" " + vbdnum + ""); - out.println(" " + mode + ""); - out.println(" "); - } - - public String getKey() { - return key; - } - - public int getDomain() { - return domain; - } - - public int getVBDNum() { - return vbdnum; - } - - public Mode getMode() { - return mode; - } + /** + * @return This device's virtual disk. + */ + public VirtualDisk getVirtualDisk() { + return vd; + } + + /** + * @return The domain this device exists in. + */ + public int getDomain() { + return domain; + } + + /** + * @return The device number within its domain. + */ + public int getVbdNum() { + return vbdNum; + } + + /** + * @return This device's access mode. + */ + public Mode getMode() { + return mode; + } } diff --git a/tools/control/src/org/xenoserver/control/VirtualDisk.java b/tools/control/src/org/xenoserver/control/VirtualDisk.java index 460570f2d3..70f61f4779 100644 --- a/tools/control/src/org/xenoserver/control/VirtualDisk.java +++ b/tools/control/src/org/xenoserver/control/VirtualDisk.java @@ -10,172 +10,224 @@ import java.util.Date; import java.util.Iterator; import java.util.Vector; +/** + * A single virtual disk. This may be used by multiple virtual block devices. + */ public class VirtualDisk { - String name; - String key; - Date expiry; - Vector extents; - - VirtualDisk(String name, Date expiry, String key) { - this.name = name; - if ( key == null ) - this.key = generate_key(); - else - this.key = key; - this.expiry = expiry; - extents = new Vector(); - } - - VirtualDisk(String name) { - this(name, null, null); - } - - VirtualDisk(String name, Date expiry) { - this(name, expiry, null); - } - - /* - * generate a unique key for this virtual disk. - * for now, just generate a 10 digit number - */ - String generate_key() { - return Long.toString(1000000000l + (long) (Math.random() * 8999999999l)); - } - - void set_expiry(Date expiry) { - this.expiry = expiry; - } - - public void add_extent(Extent extent) { - extents.add(extent); - } - - public Extent remove_extent() { - Extent e; - - if (extents.size() > 0) { - e = (Extent) extents.remove(0); - } else { - e = null; - } - - return e; - } - - String dump_xen(VirtualBlockDevice vbd) { - StringBuffer sb = new StringBuffer(); - - sb.append( - "domain:" - + vbd.domain - + " " - + vbd.mode.toString() - + " " - + "segment:" - + vbd.vbdnum - + " " - + "extents:" - + extents.size() - + " "); - for (int loop = 0; loop < extents.size(); loop++) { - Extent e = (Extent) extents.get(loop); - sb.append( - "(disk:" - + e.disk - + " " - + "offset:" - + e.offset - + " " - + "size:" - + e.size - + ")"); - } - return sb.toString(); - } - - void dump_xml(PrintWriter out) { - out.println(" "); - out.println(" " + name + ""); - out.println(" " + key + ""); - if (expiry == null) { - out.println(" 0"); - } else { - out.println(" " + expiry.getTime() + ""); - } - out.println(" "); - for (int loop = 0; loop < extents.size(); loop++) { - Extent e = (Extent) extents.get(loop); - out.println(" "); - out.println(" " + e.disk + ""); - out.println(" " + e.size + ""); - out.println(" " + e.offset + ""); - out.println(" "); - } - out.println(" "); - out.println(" "); - - return; - } - - /* - * Add a partition as a XenoPartition. - * Chop the partition in to extents and of size "size" sectors - * and add them to the virtual disk. - */ - - void add_new_partition(Partition partition, long size) { - int loop; - - for (loop = 0; loop < partition.nr_sects / size; loop++) { - Extent extent = new Extent(); - - extent.disk = partition.major << 8; - extent.disk = extent.disk | (partition.minor >> 5) << 5; - extent.size = size; - extent.offset = partition.start_sect + (size * loop); - - add_extent(extent); - } - - return; - } - - public String getName() { - return name; - } - - public String getKey() { - return key; - } - - public Date getExpiry() { - return expiry; - } - - public int getExtentCount() { - return extents.size(); - } - - public Extent getExtent(int index) { - return (Extent) extents.get(index); - } - - /** - * @return Total size of this virtual disk in sectors. - */ - public long getSize() { - long size = 0; - Iterator i = extents.iterator(); - while ( i.hasNext() ) { - size += ((Extent) i.next()).getSize(); - } - return size; - } - - /** - * @return An iterator over all extents in the disk. - */ - public Iterator iterator() { - return extents.iterator(); - } + /** The name of this virtual disk. */ + private String name; + /** The key of this virtual disk (unique). */ + private String key; + /** The expiry time of this virtual disk, or null for never. */ + private Date expiry; + /** The extent list for this virtual disk. */ + private Vector extents; + + /** + * Construct a new virtual disk, specifying all parameters. + * @param name Name of the new disk. + * @param expiry Expiry time, or null for never. + * @param key Key for the new disk, or null to autogenerate. + */ + VirtualDisk(String name, Date expiry, String key) { + this.name = name; + if (key == null) { + this.key = generateKey(); + } else { + this.key = key; + } + this.expiry = expiry; + extents = new Vector(); + } + + /** + * Construct a new virtual disk, with automatically generated key and no expiry. + * @param name Name of the new disk. + */ + VirtualDisk(String name) { + this(name, null, null); + } + + /** + * Construct a new virtual disk, with automatically generated key. + * @param name Name of the new disk. + * @param expiry Expiry time, or null for never. + */ + VirtualDisk(String name, Date expiry) { + this(name, expiry, null); + } + + /** + * Generate a unique key for this virtual disk. + * For now, just generate a 10 digit number. + * @return A unique key. + */ + private static String generateKey() { + return Long.toString( + 1000000000L + (long) (Math.random() * 8999999999L)); + } + + /** + * Add an extent to this disk. + * @param extent The extent to add. + */ + void addExtent(Extent extent) { + extents.add(extent); + } + + /** + * Remove the first extent from this disk. + * @return The extent removed, or null if there are no extents. + */ + Extent removeExtent() { + Extent e; + + if (extents.size() > 0) { + e = (Extent) extents.remove(0); + } else { + e = null; + } + + return e; + } + + /** + * Form a string suitable for passing into the XenoLinux proc interface mapping + * the given VBD to this virtual disk. + * @param vbd The virtual block device to map. + * @return A XenoLinux /proc string. + */ + String dumpForXen(VirtualBlockDevice vbd) { + StringBuffer sb = new StringBuffer(); + + sb.append( + "domain:" + + vbd.getDomain() + + " " + + vbd.getMode().toString() + + " " + + "segment:" + + vbd.getVbdNum() + + " " + + "extents:" + + extents.size() + + " "); + for (int loop = 0; loop < extents.size(); loop++) { + Extent e = (Extent) extents.get(loop); + sb.append( + "(disk:" + + e.getDisk() + + " " + + "offset:" + + e.getOffset() + + " " + + "size:" + + e.getSize() + + ")"); + } + return sb.toString(); + } + + /** + * Dump the virtual disk as XML. + * @param out The writer to dump to. + */ + void dumpAsXML(PrintWriter out) { + out.println(" "); + out.println(" " + name + ""); + out.println(" " + key + ""); + if (expiry == null) { + out.println(" 0"); + } else { + out.println(" " + expiry.getTime() + ""); + } + out.println(" "); + for (int loop = 0; loop < extents.size(); loop++) { + Extent e = (Extent) extents.get(loop); + out.println(" "); + out.println(" " + e.getDisk() + ""); + out.println(" " + e.getSize() + ""); + out.println(" " + e.getOffset() + ""); + out.println(" "); + } + out.println(" "); + out.println(" "); + + return; + } + + /** + * Add a partition as a XenoPartition. + * Chop the partition in to extents and add them to this virtual disk. + * @param partition The partition to add. + * @param extentSize The number of sectors to use for each extent. + */ + void addPartition(Partition partition, long extentSize) { + int loop; + + for (loop = 0; loop < partition.getNumSects() / extentSize; loop++) { + Extent extent = + new Extent( + partition.getDisk(), + extentSize, + partition.getStartSect() + (extentSize * loop)); + + addExtent(extent); + } + } + + /** + * @return The name of this virtual disk. + */ + public String getName() { + return name; + } + + /** + * @return The key of this virtual disk. + */ + public String getKey() { + return key; + } + + /** + * @return The expiry time of this virtual disk. + */ + public Date getExpiry() { + return expiry; + } + + /** + * @return The number of extents in this virtual disk. + */ + public int getExtentCount() { + return extents.size(); + } + + /** + * @return Total size of this virtual disk in sectors. + */ + public long getSize() { + long size = 0; + Iterator i = extents.iterator(); + while (i.hasNext()) { + size += ((Extent) i.next()).getSize(); + } + return size; + } + + /** + * @return An iterator over all extents in the disk. + */ + public Iterator extents() { + return extents.iterator(); + } + + /** + * Reset the expiry time for this virtual disk. + * @param expiry The new expiry time, or null for never. + */ + public void refreshExpiry(Date expiry) { + this.expiry = expiry; + } } diff --git a/tools/control/src/org/xenoserver/control/VirtualDiskManager.java b/tools/control/src/org/xenoserver/control/VirtualDiskManager.java index e2d1e6d6cc..7ac5e79e4d 100644 --- a/tools/control/src/org/xenoserver/control/VirtualDiskManager.java +++ b/tools/control/src/org/xenoserver/control/VirtualDiskManager.java @@ -7,230 +7,216 @@ package org.xenoserver.control; import java.io.PrintWriter; import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; +import java.util.Iterator; +import java.util.LinkedHashMap; /** * VirtualDiskManager manages the list of virtual disks on the machine. It is * a Singleton which automatically initialises itself on first class reference. */ public class VirtualDiskManager { - public static final VirtualDiskManager it = new VirtualDiskManager(); - VirtualDisk free_disk; - Vector virtual_disks; - Hashtable virtual_block_devices; - Hashtable key_hash; - - private VirtualDiskManager() { - free_disk = new VirtualDisk("free"); - - virtual_disks = new Vector(10, 5); - flush_virtual_block_devices(); - key_hash = new Hashtable(100); - } - - public VirtualDisk get_virtual_disk_key(String key) { - return ((VirtualDisk) key_hash.get(key)); - } - - public void add_xeno_partition(Partition partition, long size) { - free_disk.add_new_partition(partition, size); - return; - } - - /* - * create a new virtual disk - */ - - public VirtualDisk create_virtual_disk(String name, long size, Date expiry) { - VirtualDisk vd = new VirtualDisk(name, expiry); - - if ( free_disk.getSize() < size ) - return null; - - while (size > 0) { - Extent e; - - e = free_disk.remove_extent(); - if (e == null) { - return null; - } - size -= e.size; - vd.add_extent(e); - } - - add_virtual_disk(vd); - - return vd; - } - - /* - * delete a new virtual disk. extents go back into the free pool - */ - - public void delete_virtual_disk(String key) { - VirtualDisk vd; - - vd = (VirtualDisk) key_hash.get(key); - if (vd != null) { - Extent e; - - key_hash.remove(key); - virtual_disks.remove(vd); - - e = vd.remove_extent(); - while (e != null) { - free_disk.add_extent(e); - e = vd.remove_extent(); - } - } - return; - } - - /* - * reset the expiry time for a virtual disk - */ - - public void refresh_virtual_disk(String key, Date expiry) { - VirtualDisk vd = (VirtualDisk) key_hash.get(key); - if (vd != null) { - vd.set_expiry(expiry); - } - } - - /* - * create a new virtual block device - */ - public VirtualBlockDevice create_virtual_block_device( - String key, - int domain, - int vbd_num, - String mode) { - VirtualBlockDevice vbd = new VirtualBlockDevice(); - VirtualDisk vd = get_virtual_disk_key(key); - - if (vd == null) { - System.err.println( - "create virtual block device error: unknown key " + "[" + key + "]"); - return null; - } - - vbd.key = key; - vbd.domain = domain; - vbd.vbdnum = vbd_num; - - if (mode.equals(Mode.READ_ONLY.toString()) - || mode.equals("RO") - || mode.equals("ro")) { - vbd.mode = Mode.READ_ONLY; - } else if ( - mode.equals(Mode.READ_WRITE.toString()) - || mode.equals("RW") - || mode.equals("rw")) { - vbd.mode = Mode.READ_WRITE; - } else { - System.err.println( - "create virtual block device error: unknown mode " + "[" + mode + "]"); - return null; - } - - add_virtual_block_device(vbd); - - return vbd; - } - - /* - * delete a virtual block device - */ - public void delete_virtual_block_device(int domain, int vbd_num) { - Object hash = get_vbd_hash(domain, vbd_num); - virtual_block_devices.remove(hash); - } - - /* - * flush all virtual block devices - */ - public void flush_virtual_block_devices() { - /* isn't automatic garbage collection wonderful? */ - virtual_block_devices = new Hashtable(100); - } - - public void add_virtual_disk(VirtualDisk vd) { - virtual_disks.add(vd); - key_hash.put(vd.getKey(), vd); - } - - public void add_virtual_block_device(VirtualBlockDevice vbd) { - Object hash = get_vbd_hash(vbd.domain, vbd.vbdnum); - virtual_block_devices.put(hash, vbd); - } - - Object get_vbd_hash(int domain, int vbd_num) { - return new Integer(domain * 16 + vbd_num); - } - - public void add_free(VirtualDisk vd) { - free_disk = vd; - } - - public String dump_virtualblockdevices() { - StringBuffer sb = new StringBuffer(); - boolean first = true; - - for (Enumeration enumeration = virtual_block_devices.elements(); - enumeration.hasMoreElements(); - ) { - VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement(); - if (first) { - sb.append(vbd.dump(true)); - first = false; - } - - sb.append(vbd.dump(false)); - } - - return sb.toString(); - } - - public void dump_xml(PrintWriter out) { - out.println(""); - free_disk.dump_xml(out); - out.println(""); - out.println(""); - for (int i = 0; i < virtual_disks.size(); i++) { - VirtualDisk vd = (VirtualDisk) virtual_disks.get(i); - vd.dump_xml(out); - } - out.println(""); - out.println(""); - for (Enumeration enumeration = virtual_block_devices.elements(); - enumeration.hasMoreElements(); - ) { - VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement(); - vbd.dump_xml(out); - } - - out.println(""); - - return; - } - - /*************************************************************************/ - - public int getVirtualDiskCount() { - return virtual_disks.size(); - } - - public VirtualDisk getVirtualDisk(int index) { - return (VirtualDisk) virtual_disks.get(index); - } - - public VirtualDisk getFreeVirtualDisk() { - return free_disk; - } - - public Enumeration getVirtualBlockDevices() { - return virtual_block_devices.elements(); - } + /** The single VDM reference. */ + public static final VirtualDiskManager IT = new VirtualDiskManager(); + /** The free-space disk. */ + private VirtualDisk freeDisk; + /** The map of keys to virtual disks. */ + private LinkedHashMap virtualDisks = new LinkedHashMap(100); + /** The map of (domain,vbdnum) to virtual block devices. */ + private LinkedHashMap virtualBlockDevices = new LinkedHashMap(100); + + /** + * VDM constructor, private as it's a singleton. + */ + private VirtualDiskManager() { + freeDisk = new VirtualDisk("free"); + } + + /** + * Get the virtual disk with the specified key. + * @param key The key to look for. + * @return The virtual disk, or null if not found. + */ + public VirtualDisk getVirtualDisk(String key) { + return ((VirtualDisk) virtualDisks.get(key)); + } + + /** + * Add a new partition to the free space list in the disk manager. + * @param partition The partition to add. + * @param chunkSize The chunk size to split the partition into, in sectors. + */ + public void addPartition(Partition partition, long chunkSize) { + freeDisk.addPartition(partition, chunkSize); + } + + /** + * Create a new virtual disk. + * @param name The disk name to use. + * @param size The number of sectors to allocate. + * @param expiry The expiry time, or null for never. + * @return null if not enough space is available + */ + public VirtualDisk createVirtualDisk(String name, long size, Date expiry) { + if (freeDisk.getSize() < size) { + return null; + } + + VirtualDisk vd = new VirtualDisk(name, expiry); + + while (size > 0) { + Extent e; + + e = freeDisk.removeExtent(); + if (e == null) { + return null; + } + size -= e.getSize(); + vd.addExtent(e); + } + + insertVirtualDisk(vd); + + return vd; + } + + /** + * Delete a virtual disk, and put its extents back into the free pool. + * @param key The key of the disk to delete. + */ + public void deleteVirtualDisk(String key) { + VirtualDisk vd; + + vd = (VirtualDisk) virtualDisks.get(key); + if (vd != null) { + Extent e; + + virtualDisks.remove(key); + + e = vd.removeExtent(); + while (e != null) { + freeDisk.addExtent(e); + e = vd.removeExtent(); + } + } + } + + /** + * Create a new virtual block device. + * @param vd The virtual disk to expose. + * @param domain The domain to create the device for. + * @param vbdNum The block device number to use. + * @param mode The mode to create the device with. + * @return The newly created virtual block device. + */ + public VirtualBlockDevice createVirtualBlockDevice( + VirtualDisk vd, + int domain, + int vbdNum, + Mode mode) { + VirtualBlockDevice vbd = + new VirtualBlockDevice(vd, domain, vbdNum, mode); + + insertVirtualBlockDevice(vbd); + + return vbd; + } + + /** + * Delete a virtual block device. + * @param domain Domain owning the device. + * @param vbdNum The vbd number within the domain. + */ + public void deleteVirtualBlockDevice(int domain, int vbdNum) { + Object hash = hashVBD(domain, vbdNum); + virtualBlockDevices.remove(hash); + } + + /** + * Flush all virtual block devices. + */ + public void flushVirtualBlockDevices() { + /* isn't automatic garbage collection wonderful? */ + virtualBlockDevices = new LinkedHashMap(100); + } + + /** + * Insert a new virtual disk into the map. + * @param vd The disk to insert. + */ + void insertVirtualDisk(VirtualDisk vd) { + virtualDisks.put(vd.getKey(), vd); + } + + /** + * Insert a new virtual block device into the map. + * @param vbd The device to insert. + */ + void insertVirtualBlockDevice(VirtualBlockDevice vbd) { + Object hash = hashVBD(vbd.getDomain(), vbd.getVbdNum()); + virtualBlockDevices.put(hash, vbd); + } + + /** + * Hash a virtual block device. + * @param domain The VBD's domain. + * @param vbdNum The VBD's number within the domain. + * @return A suitable hash key. + */ + Object hashVBD(int domain, int vbdNum) { + return new Integer(domain * 16 + vbdNum); + } + + /** + * Set a new free disk. + * @param vd The free disk to set. + */ + void setFreeDisk(VirtualDisk vd) { + freeDisk = vd; + } + + /** + * Dump the data in the VirtualDiskManager in XML form. + * @param out The output writer to dump to. + */ + void dumpAsXML(PrintWriter out) { + out.println(""); + freeDisk.dumpAsXML(out); + out.println(""); + out.println(""); + Iterator i = virtualDisks.values().iterator(); + while (i.hasNext()) { + VirtualDisk vd = (VirtualDisk) i.next(); + vd.dumpAsXML(out); + } + out.println(""); + out.println(""); + i = virtualBlockDevices.values().iterator(); + while (i.hasNext()) { + VirtualBlockDevice vbd = (VirtualBlockDevice) i.next(); + vbd.dumpAsXML(out); + } + + out.println(""); + } + + /** + * @return The free disk. + */ + public VirtualDisk getFreeDisk() { + return freeDisk; + } + + /** + * @return An iterator over the virtual block devices. + */ + public Iterator getVirtualBlockDevices() { + return virtualBlockDevices.values().iterator(); + } + + /** + * @return An iterator over the virtual disks. + */ + public Iterator getVirtualDisks() { + return virtualDisks.values().iterator(); + } } diff --git a/tools/control/src/org/xenoserver/control/XML.java b/tools/control/src/org/xenoserver/control/XML.java index 55bc3a9c12..3988d8407c 100644 --- a/tools/control/src/org/xenoserver/control/XML.java +++ b/tools/control/src/org/xenoserver/control/XML.java @@ -19,107 +19,102 @@ import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; - -public class -XML -{ - static Document document = null; - /* - * dump partition manager and virtual disk manager state to filename - */ - - public static void - dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename) - { - PrintWriter out; +/** + * Utility class for loading and saving state through XML files. + */ +public class XML { + /** The document we are reading/writing. */ + private static Document document = null; - try - { - out = new PrintWriter(new BufferedWriter(new FileWriter(filename))); - } - catch (IOException e) - { - System.err.println ("XML.dump_state error [" + filename + "]"); - System.err.println (e); - return; - } + /** + * Save the state of the managers to the configuration file given. + * @param pm The PartitionManager to save. + * @param vdm The VirtualDiskManager to save. + * @param filename The configuration filename to save to. + */ + public static void saveState( + PartitionManager pm, + VirtualDiskManager vdm, + String filename) { + PrintWriter out; - out.println(""); - out.println(""); - pm.dump_xml(out); - vdm.dump_xml(out); - out.println(""); + try { + out = new PrintWriter(new BufferedWriter(new FileWriter(filename))); + } catch (IOException e) { + System.err.println("XML.dump_state error [" + filename + "]"); + System.err.println(e); + return; + } - out.close(); - return; - } + out.println(""); + out.println(""); + pm.dumpAsXML(out); + vdm.dumpAsXML(out); + out.println(""); - /* - * load partition manager and virtual disk manager state from filename - */ - public static void - load_state (PartitionManager pm, VirtualDiskManager vdm, String filename) - { - if (document == null) - { - load_file (filename); + out.close(); + return; } - XMLHelper.parse(pm, vdm, document); - } + /** + * Load the state of the managers from the given configuration file. + * @param pm The PartitionManager to load. + * @param vdm The VirtualDomainManager to load. + * @param filename The filename to read the configuration from. + */ + public static void loadState( + PartitionManager pm, + VirtualDiskManager vdm, + String filename) { + if (document == null) { + loadFile(filename); + } - /* - * load XML from disk - */ - static void - load_file (String filename) - { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - // factory.setNamespaceAware(true); - // factory.setValidating(true); + XMLHelper.parse(pm, vdm, document); + } - try - { - File file = new File(filename); + /** + * Load an XML file and parse it into a Document. + * @param filename The file to load. + */ + private static void loadFile(String filename) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - document = builder.parse(file); - } - catch (SAXParseException spe) /* error generated by parser */ - { - System.err.println ("xml parser exception on line " + - spe.getLineNumber() + - " for uri " + spe.getSystemId()); - System.err.println (spe.getMessage()); + try { + File file = new File(filename); - Exception x = spe; - if (spe.getException() != null) - x = spe.getException(); - x.printStackTrace(); - System.exit(1); - } - catch (SAXException sxe) - { - Exception e = sxe; - if (sxe.getException() != null) - e = sxe.getException(); - e.printStackTrace(); - System.exit(1); - } - catch (ParserConfigurationException pce) - { - pce.printStackTrace(); - } - catch (FileNotFoundException fnfe) - { - System.err.println ("warning: state file not found [" + - filename + "]"); - } - catch (IOException ioe) - { - ioe.printStackTrace(); + DocumentBuilder builder = factory.newDocumentBuilder(); + document = builder.parse(file); + } catch (SAXParseException spe) /* error generated by parser */ { + System.err.println( + "xml parser exception on line " + + spe.getLineNumber() + + " for uri " + + spe.getSystemId()); + System.err.println(spe.getMessage()); + + Exception x = spe; + if (spe.getException() != null) { + x = spe.getException(); + } + x.printStackTrace(); + System.exit(1); + } catch (SAXException sxe) { + Exception e = sxe; + if (sxe.getException() != null) { + e = sxe.getException(); + } + e.printStackTrace(); + System.exit(1); + } catch (ParserConfigurationException pce) { + pce.printStackTrace(); + } catch (FileNotFoundException fnfe) { + System.err.println( + "warning: state file not found [" + filename + "]"); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return; } - return; - } } diff --git a/tools/control/src/org/xenoserver/control/XMLHelper.java b/tools/control/src/org/xenoserver/control/XMLHelper.java index ad1c3f50e1..d495eb9c2c 100644 --- a/tools/control/src/org/xenoserver/control/XMLHelper.java +++ b/tools/control/src/org/xenoserver/control/XMLHelper.java @@ -8,201 +8,216 @@ package org.xenoserver.control; import java.util.Date; import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -public class -XMLHelper -{ - static void - dump_document (Document document) - { - dump_element(document.getDocumentElement(), 0); - } - - static void - dump_element (Element element, int indent) - { - NodeList nl = element.getChildNodes(); - - System.out.println ("<" + element.getTagName() + ">"); - dump_nodelist(nl, indent + 1); - System.out.println(""); - } - - static void - dump_nodelist (NodeList nl, int indent) - { - for (int loop = 0; loop < nl.getLength(); loop++) - { - Node node = nl.item(loop); - switch (node.getNodeType()) - { - case Node.ELEMENT_NODE : - { - dump_element((Element)node, indent); - break; - } - case Node.TEXT_NODE : - { - System.out.println("TEXT: " + node.getNodeValue()); - break; - } - default : - { - System.out.println("NODE: " + node.getNodeType()); - } - } - } - } - - static Node - get_subnode (String name, Node node) - { - if (node.getNodeType() != Node.ELEMENT_NODE) - { - System.err.println("Error: Search node not of element type"); - return null; +/** + * XMLHelper contains helper methods used to parse the XML state files. + */ +class XMLHelper { + /** + * Find a subnode with the specified name. + * @param name Name to look for. + * @param node Node from which to start search. + * @return The first subnode found, or null if none. + */ + private static Node getSubNode(String name, Node node) { + if (node.getNodeType() != Node.ELEMENT_NODE) { + System.err.println("Error: Search node not of element type"); + return null; + } + + if (!node.hasChildNodes()) { + return null; + } + + NodeList list = node.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + Node subnode = list.item(i); + if (subnode.getNodeType() == Node.ELEMENT_NODE) { + if (subnode.getNodeName() == name) { + return subnode; + } + } + } + return null; } - if (!node.hasChildNodes()) return null; - - NodeList list = node.getChildNodes(); - for (int i=0; i < list.getLength(); i++) - { - Node subnode = list.item(i); - if (subnode.getNodeType() == Node.ELEMENT_NODE) - { - if (subnode.getNodeName() == name) return subnode; - } - } - return null; - } - - static String - get_text (Node node) - { - StringBuffer result = new StringBuffer(); - if (node==null || !node.hasChildNodes()) return ""; - - NodeList list = node.getChildNodes(); - for (int i=0; i < list.getLength(); i++) - { - Node subnode = list.item(i); - if (subnode.getNodeType() == Node.TEXT_NODE) - { - result.append(subnode.getNodeValue()); - } - } - return result.toString(); - } - - static void - parse (PartitionManager pm, VirtualDiskManager vdm, Document document) - { - if (document == null) return; - - /* parse partitions */ - parse_partitions(pm, document.getElementsByTagName("partition")); - - /* parse virtual disks */ - NodeList list = document.getElementsByTagName("virtual_disk"); - for (int i = 0; i < list.getLength(); i++) - { - Node subnode = list.item(i); - String parent = subnode.getParentNode().getNodeName(); - VirtualDisk vd = parse_virtual_disk(subnode); - - if (parent.equals("free")) - { - vdm.add_free(vd); - } - else if (parent.equals("virtual_disks")) - { - vdm.add_virtual_disk(vd); - } - else - { - System.out.println ("XML parse error: unknown parent for virtual_disk " - + "[" + parent + "]"); - } + /** + * Get all the text of a given node. + * @param node The node to examine. + * @return The node's text. + */ + private static String getText(Node node) { + StringBuffer result = new StringBuffer(); + if (node == null || !node.hasChildNodes()) { + return ""; + } + + NodeList list = node.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + Node subnode = list.item(i); + if (subnode.getNodeType() == Node.TEXT_NODE) { + result.append(subnode.getNodeValue()); + } + } + return result.toString(); } - /* parse virtual block devices */ - parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device")); - - return; - } - - static VirtualDisk - parse_virtual_disk(Node node) - { - VirtualDisk vd; - Date date = new Date(); - NodeList list; - - long timestamp = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node))); - if ( timestamp == 0 ) - date = null; - else - date.setTime( timestamp ); - vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)), - date, - XMLHelper.get_text(XMLHelper.get_subnode("key", node))); - - list = XMLHelper.get_subnode("extents", node).getChildNodes(); - for (int i = 0; i < list.getLength(); i++) - { - Node enode = list.item(i); - - if (enode.getNodeType() == Node.ELEMENT_NODE && - enode.getNodeName().equals("extent")) - { - Extent extent = new Extent(); - - extent.disk = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("disk", enode))); - extent.size = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("size", enode))); - extent.offset = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("offset", enode))); - vd.add_extent(extent); - } + /** + * Parse the given configuration document and configure the managers. + * @param pm PartitionManager instance to configure. + * @param vdm VirtualDomainManager instance to configure. + * @param document Document to parse. + */ + static void parse( + PartitionManager pm, + VirtualDiskManager vdm, + Document document) { + if (document == null) { + return; + } + + /* parse partitions */ + parsePartitions(pm, document.getElementsByTagName("partition")); + + /* parse virtual disks */ + NodeList list = document.getElementsByTagName("virtual_disk"); + for (int i = 0; i < list.getLength(); i++) { + Node subnode = list.item(i); + String parent = subnode.getParentNode().getNodeName(); + VirtualDisk vd = parseVirtualDisk(subnode); + + if (parent.equals("free")) { + vdm.setFreeDisk(vd); + } else if (parent.equals("virtual_disks")) { + vdm.insertVirtualDisk(vd); + } else { + System.out.println( + "XML parse error: unknown parent for virtual_disk " + + "[" + + parent + + "]"); + } + } + + /* parse virtual block devices */ + parseVirtualBlockDevices( + vdm, + document.getElementsByTagName("virtual_block_device")); + + return; } - return vd; - } - - static void - parse_partitions (PartitionManager pm, NodeList nl) - { - Partition partition; - - for (int loop = 0; loop < nl.getLength(); loop++) - { - Node node = nl.item(loop); - - partition = new Partition(); - partition.major = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("major", node))); - partition.minor = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("minor", node))); - partition.blocks = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("blocks", node))); - partition.start_sect = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("start_sect", node))); - partition.nr_sects = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("nr_sects", node))); - partition.name = XMLHelper.get_text(XMLHelper.get_subnode("name", node)); + /** + * Parse a node representing a virtual disk. + * @param node The node to parse. + * @return The VirtualDisk this node represents. + */ + private static VirtualDisk parseVirtualDisk(Node node) { + VirtualDisk vd; + Date date = new Date(); + NodeList list; + + long timestamp = + Long.parseLong( + XMLHelper.getText(XMLHelper.getSubNode("expiry", node))); + if (timestamp == 0) { + date = null; + } else { + date.setTime(timestamp); + } + vd = + new VirtualDisk( + XMLHelper.getText(XMLHelper.getSubNode("name", node)), + date, + XMLHelper.getText(XMLHelper.getSubNode("key", node))); + + list = XMLHelper.getSubNode("extents", node).getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + Node enode = list.item(i); + + if (enode.getNodeType() == Node.ELEMENT_NODE + && enode.getNodeName().equals("extent")) { + Extent extent = + new Extent( + Integer.parseInt( + XMLHelper.getText( + XMLHelper.getSubNode("disk", enode))), + Long.parseLong( + XMLHelper.getText( + XMLHelper.getSubNode("size", enode))), + Long.parseLong( + XMLHelper.getText( + XMLHelper.getSubNode("offset", enode)))); + vd.addExtent(extent); + } + } + + return vd; + } - pm.add_xeno_partition(partition); + /** + * Parse a list of partition nodes. + * @param pm The partition manager to configure. + * @param nl The list of partition nodes. + */ + private static void parsePartitions(PartitionManager pm, NodeList nl) { + Partition partition; + + for (int loop = 0; loop < nl.getLength(); loop++) { + Node node = nl.item(loop); + + partition = + new Partition( + Integer.parseInt( + XMLHelper.getText(XMLHelper.getSubNode("major", node))), + Integer.parseInt( + XMLHelper.getText(XMLHelper.getSubNode("minor", node))), + Integer.parseInt( + XMLHelper.getText( + XMLHelper.getSubNode("blocks", node))), + Integer.parseInt( + XMLHelper.getText( + XMLHelper.getSubNode("start_sect", node))), + Integer.parseInt( + XMLHelper.getText( + XMLHelper.getSubNode("nr_sects", node))), + XMLHelper.getText(XMLHelper.getSubNode("name", node)), + true); + + pm.addXenoPartition(partition); + } } - } - - static void - parse_virtual_block_devices (VirtualDiskManager vdm, NodeList nl) - { - for (int loop = 0; loop < nl.getLength(); loop++) - { - Node node = nl.item(loop); - - vdm.create_virtual_block_device(XMLHelper.get_text(XMLHelper.get_subnode("key", node)), - Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("domain", node))), - Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))), - XMLHelper.get_text(XMLHelper.get_subnode("mode", node))); + + /** + * Parse a list of virtual block device nodes. + * @param vdm The VirtualDiskManager to configure. + * @param nl The node list. + */ + private static void parseVirtualBlockDevices( + VirtualDiskManager vdm, + NodeList nl) { + for (int loop = 0; loop < nl.getLength(); loop++) { + Node node = nl.item(loop); + Mode mode; + + if (XMLHelper + .getText(XMLHelper.getSubNode("mode", node)) + .equals("rw")) { + mode = Mode.READ_WRITE; + } else { + mode = Mode.READ_ONLY; + } + + vdm.createVirtualBlockDevice( + vdm.getVirtualDisk( + XMLHelper.getText(XMLHelper.getSubNode("key", node))), + Integer.parseInt( + XMLHelper.getText(XMLHelper.getSubNode("domain", node))), + Integer.parseInt( + XMLHelper.getText(XMLHelper.getSubNode("vbdnum", node))), + mode); + } } - } } -- 2.30.2